<?php
namespace core\utils;
use core\utils\Bean;

/**
 * 通过CURL发起请求
 * Class CurlUtil
 * @package core\utils
 */
class CurlUtil implements Bean {
    /**
     * 发起 GET 形式的请求
     * @param string $url   请求的url
     * @param array $param  请求的参数
     * @param array $cookie 请求的cookie
     * @param array $option 请求的CURLOPT
     * @return string       请求返回的内容
     */
    public static function get(string $url, array $param = [], array $cookie = [], array $option = []) {
        $handle = curl_init();
        if (strpos($url, '?') !== false) {
            $url .= '&'.self::httpBuildParam($param);
        } else {
            $url .= '?'.$url;
        }
        curl_setopt($handle, CURLOPT_URL, $url);
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);

        curl_setopt($handle, CURLOPT_COOKIE, self::httpBuildCookie($cookie));

        self::setOptions($handle, $option);

        $res = curl_exec($handle);
        curl_close($handle);
        return $res;
    }

    /**
     * 发起 POST 形式的请求
     * @param string $url 请求的url
     * @param $param
     * @param array $cookie 请求的cookie
     * @param array $header 请求头
     * @param array $option 请求的CURLOPT
     * @return string       请求返回的内容
     */
    public static function post(string $url, $param = [], array $cookie = [], array $header = [],array $option = []) {
        $handle = curl_init();
        curl_setopt($handle, CURLOPT_URL, $url);
        curl_setopt($handle, CURLOPT_POST, true);
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($handle, CURLOPT_POSTFIELDS, self::httpBuildParam($param));
        if ($header) {
            curl_setopt($handle, CURLOPT_HEADER, $header);
        }
        curl_setopt($handle, CURLOPT_COOKIE, self::httpBuildCookie($cookie));

        self::setOptions($handle, $option);

        $res = curl_exec($handle);
        curl_close($handle);
        return $res;
    }

    /**
     * 设置curl的options
     * @param resource $handle  curl的handle
     * @param array $options    CURLOPT s
     */
    private static function setOptions($handle, array $options) {
        foreach ($options as $k=>$v) {
            curl_setopt($handle, $k, $v);
        }
    }

    /**
     * 把cookie数组转换成cookie字符串
     * @param array $cookieArray
     * @return string
     */
    private static function httpBuildCookie(array $cookieArray) : string {
        $res = '';
        foreach ($cookieArray as $k => $v) {
            $res .= $k . '=' . $v . ';';
        }
        return $res;
    }

    /**
     * 参数转换成字符串
     * @param $params
     * @return string
     */
    private static function httpBuildParam($params) : string {
        if (is_string($params)) {
            return $params;
        }
        $res = '';
        foreach ($params as $k=>$v) {
            if (is_array($v)) {
                foreach ($v as $vv) {
                    $res .= '&'.$k.'[]='.$vv;
                }
            } elseif (is_string($v)) {
                $res .= '&'.$k.'='.$v;
            }
        }
        return ltrim($res, '&');
    }
}